<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="1145px" preserveAspectRatio="none" style="width:1214px;height:1145px;background:#FEFEFE;" version="1.1" viewBox="0 0 1214 1145" width="1214px" zoomAndPan="magnify"><defs/><g><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="18" lengthAdjust="spacingAndGlyphs" textLength="287" x="461.5" y="27.4023">OAuth Consent and Refresh Flow</text><line style="stroke: #383838; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="120" x2="120" y1="86.6875" y2="1088.041"/><line style="stroke: #383838; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="419.5" x2="419.5" y1="86.6875" y2="1088.041"/><line style="stroke: #383838; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="839" x2="839" y1="86.6875" y2="1088.041"/><line style="stroke: #383838; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="985" x2="985" y1="86.6875" y2="1088.041"/><line style="stroke: #383838; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="1107" x2="1107" y1="86.6875" y2="1088.041"/><rect fill="#F8F8F8" height="30.4883" style="stroke: #383838; stroke-width: 1.5;" width="69" x="86" y="55.1992"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="55" x="93" y="75.7344">Browser</text><rect fill="#F8F8F8" height="30.4883" style="stroke: #383838; stroke-width: 1.5;" width="69" x="86" y="1087.041"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="55" x="93" y="1107.5762">Browser</text><rect fill="#F8F8F8" height="30.4883" style="stroke: #383838; stroke-width: 1.5;" width="116" x="361.5" y="55.1992"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="102" x="368.5" y="75.7344">Popup Window</text><rect fill="#F8F8F8" height="30.4883" style="stroke: #383838; stroke-width: 1.5;" width="116" x="361.5" y="1087.041"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="102" x="368.5" y="1107.5762">Popup Window</text><rect fill="#F8F8F8" height="30.4883" style="stroke: #383838; stroke-width: 1.5;" width="159" x="760" y="55.1992"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="145" x="767" y="75.7344">auth-backend plugin</text><rect fill="#F8F8F8" height="30.4883" style="stroke: #383838; stroke-width: 1.5;" width="159" x="760" y="1087.041"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="145" x="767" y="1107.5762">auth-backend plugin</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="107" x="929" y="83.7344">Consent Screen</text><ellipse cx="985.5" cy="54.1992" fill="#F8F8F8" rx="12" ry="12" style="stroke: #383838; stroke-width: 2.0;"/><polygon fill="#383838" points="981.5,42.1992,987.5,37.1992,985.5,42.1992,987.5,47.1992,981.5,42.1992" style="stroke: #383838; stroke-width: 1.0;"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="107" x="929" y="1100.5762">Consent Screen</text><ellipse cx="985.5" cy="1119.5293" fill="#F8F8F8" rx="12" ry="12" style="stroke: #383838; stroke-width: 2.0;"/><polygon fill="#383838" points="981.5,1107.5293,987.5,1102.5293,985.5,1107.5293,987.5,1112.5293,981.5,1107.5293" style="stroke: #383838; stroke-width: 1.0;"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="105" x="1052" y="83.7344">OAuth Provider</text><ellipse cx="1107.5" cy="54.1992" fill="#F8F8F8" rx="12" ry="12" style="stroke: #383838; stroke-width: 2.0;"/><line style="stroke: #383838; stroke-width: 2.0;" x1="1095.5" x2="1119.5" y1="68.1992" y2="68.1992"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="105" x="1052" y="1100.5762">OAuth Provider</text><ellipse cx="1107.5" cy="1119.5293" fill="#F8F8F8" rx="12" ry="12" style="stroke: #383838; stroke-width: 2.0;"/><line style="stroke: #383838; stroke-width: 2.0;" x1="1095.5" x2="1119.5" y1="1133.5293" y2="1133.5293"/><path d="M8,101.6875 L8,156.6875 L233,156.6875 L233,111.6875 L223,101.6875 L8,101.6875 " fill="#ECECEC" style="stroke: #383838; stroke-width: 1.0;"/><path d="M223,101.6875 L223,111.6875 L233,111.6875 L223,101.6875 " fill="#ECECEC" style="stroke: #383838; stroke-width: 1.0;"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="201" x="14" y="119.2559">Components on page ask for an</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="161" x="14" y="134.5664">access token with greater</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="204" x="14" y="149.877">scope than the existing session.</text><polygon fill="#383838" points="407.5,179.9297,417.5,183.9297,407.5,187.9297,411.5,183.9297" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="120.5" x2="413.5" y1="183.9297" y2="183.9297"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="77" x="127.5" y="179.1875">Open popup</text><polygon fill="#383838" points="827.5,209.2402,837.5,213.2402,827.5,217.2402,831.5,213.2402" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="419.5" x2="833.5" y1="213.2402" y2="213.2402"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="333" x="426.5" y="208.498">GET /auth/&lt;provider&gt;/start?scope=some%20scopes</text><polygon fill="#383838" points="430.5,269.1719,420.5,273.1719,430.5,277.1719,426.5,273.1719" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="424.5" x2="838.5" y1="273.1719" y2="273.1719"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="198" x="436.5" y="237.8086">Redirect to consent screen with</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="212" x="436.5" y="253.1191">random nonce in OAuth state and</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="255" x="436.5" y="268.4297">short-lived cookie with the same nonce.</text><polygon fill="#383838" points="973.5,313.793,983.5,317.793,973.5,321.793,977.5,317.793" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="419.5" x2="979.5" y1="317.793" y2="317.793"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="369" x="426.5" y="297.7402">GET /consent_url?redirect_uri=&lt;redirect_uri&gt;?nonce=&lt;n&gt;</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="422" x="426.5" y="313.0508">where redirect_uri=&lt;app-origin&gt;/auth/&lt;provider&gt;/handler/frame</text><path d="M905,330.793 L905,370.793 L1066,370.793 L1066,340.793 L1056,330.793 L905,330.793 " fill="#ECECEC" style="stroke: #383838; stroke-width: 1.0;"/><path d="M1056,330.793 L1056,340.793 L1066,340.793 L1056,330.793 " fill="#ECECEC" style="stroke: #383838; stroke-width: 1.0;"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="106" x="911" y="348.3613">User consents to</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="140" x="911" y="363.6719">access the new scope.</text><polygon fill="#383838" points="430.5,393.7246,420.5,397.7246,430.5,401.7246,426.5,397.7246" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="424.5" x2="984.5" y1="397.7246" y2="397.7246"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="343" x="436.5" y="392.9824">Redirect to given redirect URL, with authorization code</text><polygon fill="#383838" points="827.5,438.3457,837.5,442.3457,827.5,446.3457,831.5,442.3457" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="419.5" x2="833.5" y1="442.3457" y2="442.3457"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="396" x="426.5" y="422.293">GET /auth/&lt;provider&gt;/handler/frame?code=&lt;c&gt;&amp;nonce=&lt;n&gt;</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="304" x="426.5" y="437.6035">Request includes the previously set none cookie</text><path d="M710,455.3457 L710,495.3457 L969,495.3457 L969,465.3457 L959,455.3457 L710,455.3457 " fill="#ECECEC" style="stroke: #383838; stroke-width: 1.0;"/><path d="M959,455.3457 L959,465.3457 L969,465.3457 L959,455.3457 " fill="#ECECEC" style="stroke: #383838; stroke-width: 1.0;"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="217" x="716" y="472.9141">Verify that the nonce in the cookie</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="238" x="716" y="488.2246">matches the nonce in the OAuth state</text><polygon fill="#383838" points="1095.5,548.8984,1105.5,552.8984,1095.5,556.8984,1099.5,552.8984" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="839.5" x2="1101.5" y1="552.8984" y2="552.8984"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="122" x="846.5" y="517.5352">Authorization Code</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="55" x="846.5" y="532.8457">Client ID</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="79" x="846.5" y="548.1563">Client Secret</text><path d="M1013,565.8984 L1013,590.8984 L1202,590.8984 L1202,575.8984 L1192,565.8984 L1013,565.8984 " fill="#ECECEC" style="stroke: #383838; stroke-width: 1.0;"/><path d="M1192,565.8984 L1192,575.8984 L1202,575.8984 L1192,565.8984 " fill="#ECECEC" style="stroke: #383838; stroke-width: 1.0;"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="168" x="1019" y="583.4668">Verify and generate tokens</text><polygon fill="#383838" points="850.5,674.7617,840.5,678.7617,850.5,682.7617,846.5,678.7617" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="844.5" x2="1106.5" y1="678.7617" y2="678.7617"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="87" x="856.5" y="612.7773">Access Token</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="65" x="856.5" y="628.0879">(ID Token)</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="98" x="856.5" y="643.3984">(Refresh Token)</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="37" x="856.5" y="658.709">Scope</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="74" x="856.5" y="674.0195">Expire Time</text><polygon fill="#383838" points="430.5,719.3828,420.5,723.3828,430.5,727.3828,426.5,723.3828" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="424.5" x2="838.5" y1="723.3828" y2="723.3828"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="300" x="436.5" y="703.3301">Small HTML page with inlined response payload</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="260" x="436.5" y="718.6406">Store Refresh Token in HTTP-only cookie</text><polygon fill="#383838" points="131.5,748.6934,121.5,752.6934,131.5,756.6934,127.5,752.6934" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="125.5" x2="418.5" y1="752.6934" y2="752.6934"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="275" x="137.5" y="747.9512">postMessage() with tokens and info or error</text><line style="stroke: #383838; stroke-width: 1.0;" x1="419.5" x2="461.5" y1="782.0039" y2="782.0039"/><line style="stroke: #383838; stroke-width: 1.0;" x1="461.5" x2="461.5" y1="782.0039" y2="795.0039"/><line style="stroke: #383838; stroke-width: 1.0;" x1="420.5" x2="461.5" y1="795.0039" y2="795.0039"/><polygon fill="#383838" points="430.5,791.0039,420.5,795.0039,430.5,799.0039,426.5,795.0039" style="stroke: #383838; stroke-width: 1.0;"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="62" x="426.5" y="777.2617">Close self</text><path d="M9,808.0039 L9,863.0039 L232,863.0039 L232,818.0039 L222,808.0039 L9,808.0039 " fill="#ECECEC" style="stroke: #383838; stroke-width: 1.0;"/><path d="M222,808.0039 L222,818.0039 L232,818.0039 L222,808.0039 " fill="#ECECEC" style="stroke: #383838; stroke-width: 1.0;"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="174" x="15" y="825.5723">A later point when a refresh</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="176" x="19" y="840.8828">is needed. Either because of</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="198" x="19" y="856.1934">a reload or an expiring session.</text><polygon fill="#383838" points="827.5,901.5566,837.5,905.5566,827.5,909.5566,831.5,905.5566" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="120.5" x2="833.5" y1="905.5566" y2="905.5566"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="185" x="127.5" y="885.5039">GET /auth/&lt;provider&gt;/token</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="194" x="127.5" y="900.8145">Refresh Token cookie included</text><polygon fill="#383838" points="1095.5,961.4883,1105.5,965.4883,1095.5,969.4883,1099.5,965.4883" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="839.5" x2="1101.5" y1="965.4883" y2="965.4883"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="90" x="846.5" y="930.125">Refresh Token</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="55" x="846.5" y="945.4355">Client ID</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="79" x="846.5" y="960.7461">Client Secret</text><polygon fill="#383838" points="850.5,1036.7305,840.5,1040.7305,850.5,1044.7305,846.5,1040.7305" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="844.5" x2="1106.5" y1="1040.7305" y2="1040.7305"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="87" x="856.5" y="990.0566">Access Token</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="65" x="856.5" y="1005.3672">(ID Token)</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="37" x="856.5" y="1020.6777">Scope</text><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="74" x="856.5" y="1035.9883">Expire Time</text><polygon fill="#383838" points="131.5,1066.041,121.5,1070.041,131.5,1074.041,127.5,1070.041" style="stroke: #383838; stroke-width: 1.0;"/><line style="stroke: #383838; stroke-width: 1.0;" x1="125.5" x2="838.5" y1="1070.041" y2="1070.041"/><text fill="#000000" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="102" x="137.5" y="1065.2988">Tokens and info</text><!--MD5=[c025fb26ac34956dc15457f201ee7a22]
@startuml /../assets/auth/oauth-popup-flow

skinparam monochrome true
skinparam shadowing false
skinparam backgroundColor #fefefe
skinparam defaultFontName Segoe UI, Helvetica, Arial, sans-serif

title OAuth Consent and Refresh Flow

participant Browser
participant "Popup Window" as Popup
participant "auth-backend plugin" as Backend
control "Consent Screen" as Consent
entity "OAuth Provider" as Provider

note over Browser: Components on page ask for an\naccess token with greater\nscope than the existing session.

Browser -> Popup: Open popup
Popup -> Backend: GET /auth/<provider>/start?scope=some%20scopes
Popup <- Backend: Redirect to consent screen with\nrandom nonce in OAuth state and\nshort-lived cookie with the same nonce.
Popup -> Consent: GET /consent_url?redirect_uri=<redirect_uri>?nonce=<n>\nwhere redirect_uri=<app-origin>/auth/<provider>/handler/frame

note over Consent: User consents to\naccess the new scope.

Popup <- Consent: Redirect to given redirect URL, with authorization code
Popup -> Backend: GET /auth/<provider>/handler/frame?code=<c>&nonce=<n>\nRequest includes the previously set none cookie

note over Backend: Verify that the nonce in the cookie\nmatches the nonce in the OAuth state

Backend -> Provider: Authorization Code\nClient ID\nClient Secret

note over Provider: Verify and generate tokens

Backend <- Provider: Access Token\n(ID Token)\n(Refresh Token)\nScope\nExpire Time
Popup <- Backend: Small HTML page with inlined response payload\nStore Refresh Token in HTTP-only cookie
Browser <- Popup: postMessage() with tokens and info or error
Popup -> Popup: Close self

note over Browser: A later point when a refresh\n is needed. Either because of\n a reload or an expiring session.

Browser -> Backend: GET /auth/<provider>/token\nRefresh Token cookie included
Backend -> Provider: Refresh Token\nClient ID\nClient Secret
Backend <- Provider: Access Token\n(ID Token)\nScope\nExpire Time
Browser <- Backend: Tokens and info

@enduml

PlantUML version 1.2020.16(Mon Aug 24 01:50:43 IST 2020)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
Default Encoding: UTF-8
Language: en
Country: GB
--></g></svg>
